 PAG
********************************
* SEGZEROFONE
********************************

 ORG $C800  ;2K SLOT

* THE FOLLOWING IS RUN FROM THE CARD SLOT SPACE.
*
* NOTE! THE IIGS MUST BE IN EMULATION MODE

* THIS IS FIRST INSTRUCTION IN EPROM

START1 SEC
 BCS STAYIN

*-------------------------------------
* --- Alternate entry point ---
* Start here if you want the DDT card to do an RTS after it is
* initialized.
* The contents of the Accumulator determine the return condition as follows:
* A = 02 The button & BRKs are not enabled, writing to DDT is enabled,
*        accessing the vectors $FFE8-$FFFF is OK.
* A = 03 The button is the only way back into the DDT. Accessing the vectors
*        is OK. The DDT is write protected.
* A = XX The button & BRKs are enabled, writing to DDT is enabled, accessing
*        the vectors will disable the Apples ROM in the $FFxx addresses.  

START2 CLC
STAYIN STA $CFFF  ;GET 2K SPACE
 NOP   ;SPECIAL LOCATION
 JSR SAVEREG  ;SAVE REGISTERS, RAMRD & RAMWRT
 LDA #$A2  ;$A2 IS DEVICE SIGNATURE		
 ROR STRT2FLG ;BIT 7=0 DO AN RTS AFTER INITIALIZATION.

* DETERMINE SLOT NUMBER
 JSR PUTSLOT  ;PUT SLOT NUMBER ON STACK
 TSX
 LDA $0100,X
**********************************
* GO TO 2K SLOT
**********************************

 JMP SLOT2K

*---------------------------------------------------
*  --- Warm entry --
* Enter here after the DDT is initialized to preserve the user's settings.
* Reset vectored here from 6502 or 65816
* Also used as return point from COMDDO user subroutine

RESETJMP
 STA $CFFF
 JSR SAVEREG  ;SAVE REGISTERS
 SEC
 ROR INITFLAG ;INDICATE USER MAY HAVE MESSED WITH SCREEN
 JMP ENTEREXT ;DISPLAY MAIN SCREEN AND AWAIT COMMAND

* NMI VECTORED HERE FROM 6502

NMIJUMP CMP $CFFF
 JMP NMIVEC  ;THIS INSTRUCTION IN SLOT ROM SPACE
    ;JUMPS TO THE NMI HANDLER IN 2K SPACE

* NMI VECTORED HERE FROM 65816

NMI816 CMP $CFFF  ;2K OFF
 JMP NMIVEC16 ;GOTO NMI ROUTINE

* BRK VECTORED HERE FROM 65816

BREAK816
 CMP $CFFF  ;2K OFF
 JMP BRKVEC16 ;GOTO BRK ROUTINE

* IRQ VECTORED HERE FROM 6502

IRQJUMP CMP $CFFF  ;GET 2K SLOT
 STA ACC  ;SAVE ACC
 STA ZBYTE1
 PLA   ;GET CXROM STATUS OFF STACK
 STA CXSTATUS ;SAVE
 PLA   ;GET STATUS
 PHA
 AND #$10
 BEQ IRQ  ;INTERRUPT WAS CAUSED BY IRQ
 JMP BREAK  ;INT WAS CAUSED BY BRK
IRQ LDA $FFFF  ;- HI BYTE OF APPLES IRQ VECTOR
 PHA   ;-
 LDA $FFFE  ;- LOW BYTE
 PHA   ;-
 PHP   ;- ANY STATUS WILL DO
 CLC
 BCC IRQENTRY ;BRA TO ACTIVATE PERIPHERAL CARD

** ENABLE THE EXTERMINATORS 2K SLOT

EXTENAB STA $CFFF  ;DISABLE 2K SLOT
 RTS   ;RETURN TO CALLING PROGRAM

**********************************
* THIS POINT MUST BE BEFORE $CN7F
**********************************
 ERR *-1/$C87F

* RETURN FROM I/O ROUTINES TO CARD SLOT SPACE

SLOTRTS EQU *-1  ;EQUATE FOR RTS
 STA $CFFF  ;DISABLE 2K

 STA ZBYTE1  ;SAVE
 STX ZBYTE2
 STY ZBYTE3
 TSX
 LDY #5
:MORE LDA STKBUF,Y ;RESTORE 6 BYTES OF STACK IN THIS SEG
 STA $100,X
 DEX
 DEY
 BPL :MORE

 STA MAINZP  ;MAIN STACK
 BIT INDYBUF  ;MAIN OR AUX STACK ?
 BPL :MAIN  ;MAIN
 STA AUXZP  ;AUX STACK
:MAIN JMP RTSCONT  ;CONTINUE IN 2K SLOT

****************************************
* THIS POINT MUST BE AFTER $Cn7F
****************************************
 ERR $C87F/*

***** EXECUTE THE USERS PROGRAM *****

TOEXECUT EQU *-1 ;EQUATED FOR RTS
 LDA #%11011110 ;CB2 LOW, CB1 POS EDGE, CA2 HI, CA1 NEG EDGE
 STA VIAPCR  ;REPLACE APPLE'S VECTORS
 LDX STACK  ;USE THIS STACK
 TXS

 BIT EMULATE  ;816 MODE?
 BMI NOPBR  ;IF NO
 LDA PBR  ;GET PROGRAM BANK REG.
 PHA   ;ON STACK LIKE 816 INTERRUPT

NOPBR LDA PCHI  ;-
 PHA   ;-
 LDA PCLO  ;-SET UP STACK FOR RTI
 PHA

 LDA STATUS  ;-
 PHA   ;-

 ORA #$20  ;INDEXES BACK TO ORIGINAL FORM KEEP ACC 8 BIT
 PHA
 PLP
 CLD   ;KEEP D CLEAR

 LDX XREG  ;8 OR 16 BITS
 LDY YREG
 LDA #$FF
 STA VIAIFR  ;CLEAR OLD INTERRUPT FLAGS
 LDA IERBUFF  ;GET INTERRUPT FLAGS FROM BUFFER
 STA VIAIER  ;ENABLE INTERRUPTS

******************************
* TIME CRITICAL BELOW THIS POINT
******************************

 LDA #00
 STA VIAT2CH  ;FOR EXECUTION TIME, DOES NOT CAUSE NMI
 STA VIAT1CH  ;STORE 00 IN COUNTER1, WILL CAUSE NMI ONLY
*IF IT HAS BEEN ENABLED IN TRACE ROUTINE.

* GO TO ROUTINE IN CARDS I/O SPACE BY PUTING THE ADDRESS
* ON THE STACK AND USING AN RTS.
* IF IRQ ENTRY, I/O SPACE ROUTINE MUST HAVE BEEN SETUP FOR
* EXECUTE IF WE TRAPPED AN IRQ, SO ITS OK TO GO TO I/O

SLOTIO EQU *-1
IRQENTRY
 LDA #$C0  ;I/O SPACE HI BYTE
 PHA
 CLC
 BIT CXSTATUS ;WAS CXROM ON?
 BPL CXWASOFF ;KEEP CXROM OFF
*CXROM WAS ON
 LDA #CXONRTI-1 ;LOW BYTE
GOTOIO ADC SLOTN0  ;SET FOR THIS SLOT
 PHA   ;PUT LOW ADDR. BYTE ON STACK
 LDA ZBYTE1  ;RESTORE
 CMP $CFFF  ;2K ROMS OFF
 RTS   ;GOTO I/O SPACE ROUTINE POINTED TO BY STACK
*THIS PATH MUST TAKE 4 CYCLES LONGER BECAUSE OF THE
*DIFFERENCE IN I/O SPACE ROUTINES
CXWASOFF
 LDA #CXOKRTI-1
 BNE GOTOIO  ;<ALWAYS> 3CYCLES + 1 EXTRA CYCLE FOR
    ;BRANCHING TO CXWASOFF =4

*----------------------------------------
* Pascal 1.1 slot interface
*
* Call the firmware routine specified bye the Acc in the
* Pascal V1.1 compatible device in slot 1 or 2. Enter with:
* IORETRN-1 pushed on stack for return address.
* C1 or C2 pushed on stack as part of simulated JSR
* V=0 slot2, V=1 slot1
* Acc = offset to Pascal entry point offset.
* X = character to write if writing or status request code.

TOPASCAL EQU *-1 ;EQU for RTS
 TAY ;offset to Pascal firmware routine
 CMP $CFFF ;disable 2K ROMS
 BVC :SLOT2 ;if slot 2
 BIT $C100 ;enable slot 1
 LDA $C100,Y ;Pascal firmware offset
 DEC  ;offset - 1
 PHA  ;low byte of firmware offset -1
 TXA  ;character to send if writing or request code
 LDX #$C1 ;slot 1
 LDY #$10 ;slot 1
 RTS  ;simulate JSR to Pascal firmware

:SLOT2 BIT $C200 ;enable slot 2
 LDA $C200,Y ;Pascal firmware offset
 DEC  ;offset - 1
 PHA  ;low byte of firmware offset -1
 TXA  ;character to send if writing or request code
 LDX #$C2 ;slot 2
 LDY #$20 ;slot 2
 RTS ;simulate JSR to Pascal firmware

 ERR *-1/$C900
*********************************
* STARTING SEGMENT 0 OF 2K SLOT.
*********************************

 ASC "'Prodev' is a trademark of "
 ASC "Prodev, Inc. with "
 ASC "all rights reserved. "
 ASC "This program is property of Prodev, Inc. "
 ASC "Copyright 1985,1986,1987,1988 by: "  
 ASC "Prodev, Inc. "
 ASC "P.O. Box 162, LaSalle, MI, 48145 "  
 ASC "(313) 848-4012"

 ERR *-1/$CA00
*******************************************
* MAKE SURE THIS POINT IS $CA00 OR HIGHER *
*******************************************

 DS $CA00-*,$FF

* THIS ROUTINE MUST RESIDE IN SEGMENT ZERO

* BREAK FROM 65816

BRKVEC16
  JSR INDEXTO8 ;SAVE 16 BIT INDEXES & SET TO 8 BIT
 PLA   ;GET CXROM STATUS OFF STACK
 STA CXSTATUS ;SAVE
 BRA BRK16

* BREAK FROM 6502

BREAK SEC
 ROR EMULATE  ;NOT 65816 MODE
BRK16 PLA   ;GET STATUS
 JSR SAVXYSP  ;SAVE ALL REGS BUT ACC & RAMRD, RAMWRT.
 JSR ENABWRIT ;DISABLE INTRUPTS, DON'T REPLACE APPLE VECTORS
 PLA
 SEC
 SBC #2  ;CORRECT FOR THE WAY THE BRK INST WORKS
 STA PCLO  ;SAVE LOW BYTE OF PC
 PLA
 SBC #0  ;SUBTRACT CARRY BIT (NOT C) IF NECESSARY
 STA PCHI  ;SAVE HI BYTE OF PC
 STA MEMHI  ;USED BY SETMPBR

 BIT EMULATE  ;816 MODE?
 BMI :BRK02  ;IF NO
 PLA   ;GET PBR FROM STACK
 BRA :BRK816

* SET MEMPBR
:BRK02 JSR TRANSFR0 ;DO SETMSTAT & BANKCHEK
 DFB SETMPBRC ;code  ACC = MEMPBR

:BRK816 STA PBR  ;SAVE
 TSX
 STX STACK  ;CORRECT STACK IF 816

 LDA #$FF
 STA INITFLAG ;SET FLAG THAT USER'S PROGRAM HAS BEEN RUN.

 STA PASSFLG  ;CONTINUE WITH GO AFTER TRACING
 JMP LOOKBRK  ; THRU BRK

* NMI FROM 65816

NMIVEC16
 JSR INDEXTO8 ;SAVE 16 BIT INDEXES & SET TO 8 BIT
 BRA NMI16

* NMI FROM 6502

* YOU CAN WRITE TO RAM DURING BUTTON INTERRUPT UNTIL
* THE BUTTON INPUT CAPACITOR CHARGES TO 0.6V (APPROX. 1MSEC)

NMIVEC STA ACC  ;SAVE
 SEC
 ROR EMULATE  ;NOT 65816 MODE
NMI16 PLA   ;GET CXSTATUS OFF STACK
 STA CXSTATUS
 LDA VIAIFR  ;VIA INTERRUPT FLAG REG.
 BMI OURNMI  ;IT'S OURS
 PLA   ;GET STATUS WHEN NMI OCCURED
 STA STATUS  ;SAVE
 PHA   ;RESTORE

 BIT EMULATE  ;16 BIT MODE?
 BMI GOVEC8  ;IF NO
*16 BIT
* PHK PUSH PBR ON STACK

 LDA #%11011110 ;CB2 LOW, CB1 POS, CA2 HI, CA1 NEG
 STA VIAPCR  ;PUT PCR BACK
 phk   ;PUSH PBR ON STACK
 LDA $FFEB  ;HI BYTE OF APPLE'S 65816 NMI VECTOR
 PHA
 LDA $FFEA  ;LOW BYTE
 PHA
 bra TOIOJUMP
* 8 BIT
GOVEC8 LDA $FFFB  ;HI BYTE OF APPLE'S 6502 NMI VECTOR
 PHA
 LDA $FFFA  ;LOW BYTE
 PHA
TOIOJUMP
 LDA STATUS  ;GET STATUS WHEN NMI OCCURRED
 PHA   ;PUT ORIG. STATUS SO MACHINE IN SAME STATE
 LDA ACC  ;RESTORE ACC
 BIT CXSTATUS
 BPL SLOTOK  ;LEAVE CXROM OFF
 JMP CXONRTI+$50 ;TURN CXROM ON & GOTO APPLES NMI ROUTINE.
SLOTOK JMP CXOKRTI+$50 ;LEAVE CXROM OFF & GOTO APPLE'S NMI ROUTINE

* ENABWRIT MUST BE EXECUTED BEFORE THE CAPACITOR ON THE
* BUTTON INPUT IS CHARGED TO 0.6V (APPROX. 1MSEC)

OURNMI JSR ENABWRIT ;DISABLE INTERRUPTS & ENABLE EXT. FOR WRITE
 LDA VIAACR
 ORA #%00100000 ;STOP T2 COUNT INCASE OF ET COMMAND
 STA VIAACR
 PLA   ;GET STATUS
 JSR SAVXYSP  ;SAVE X,Y,S & P REG & RAMRD & RAMWRT
 PLA
 STA PCLO
 PLA
 STA PCHI
 STA MEMHI  ;USED BY SETMPBR
 LDA EMULATE  ;816 MODE?
 BMI :NMI02  ;IF NO
 PLA   ;GET PBR FROM STACK
 BRA :NMI816

* SET MEMPBR WITH CURRENT BANK #

:NMI02 JSR TRANSFR0 ;DO SETMSTAT AND BANKCHEK
 DFB SETMPBRC ;code,  ACC CONTAINS MEMPBR

:NMI816 STA PBR  ;SAVE
 TSX
 STX STACK  ;CORRECT STACK IF 816

* SETTING INITFLAG CAUSES THE TEXT PAGE & SWITCHES TO BE SAVED
* BY THE EXTII OUTPUT ROUTINES IF INVISIBLE MODE IS ON.

 LDA #$FF  ;SET FLAG TO INDICATE THAT USER'S
 STA INITFLAG ; PROGRAM HAS BEEN RUN.
 CLD
 LDA VIAIFR  ;GET INTERRUPT FLAG REG.
 AND IERBUFF  ;TEST ONLY THOSE BITS THAT ARE ENABLED
 LSR   ;SHIFT ACC RIGHT TWO BITS
 LSR
 BCC NOTBUTON ;NOT BUTTON INPUT

* SAVE THE STACK, WINDOW LIMITS AND PAGE #1 OF TEXT RAM.

 JSR SAVESTK  ;SAVE THE STACK TO EXT
 JMP COMMDRCL ;IF BUTTON

NOTBUTON
 LSR   ;SHIFT 0 IN
 LSR
 LSR
 BCC NOTHBR  ;NOT HARDWARE BREAKPOINT
 BIT ETFLAG  ;WAS HARD BREAK CAUSED BY ET
 BMI CONTNMI  ;IF YES

 LDA PBR
 CMP HARDPBR  ;STOP IN THIS BANK?
 BEQ :HARDSTP ;IF YES
 BIT TFLAG  ;TRACING ?
 BMI NOTHBR  ;IF YES
 JMP EXECUTE  ;IF NO
  
:HARDSTP
 JSR SVESTK16 ;SAVE 16 BYTES ABOVE STACK POINTER
 JSR TRANSFR0 ;DISPLAY "HARD BREAK"
 DFB DISHARDC ;CODE
COMMDRCL
 LDA #%10111111
 AND IERBUFF  ;DISABLE VIAT1 (TRACE)
 STA IERBUFF
 JMP COMDDR

NOTHBR
 LDX TXSFLG  ;WAS LAST INST A TXS OR TCS?
 BEQ SVESCONT ;IF NO 

* LAST INST WAS TXS OR TCS SO RESTORE 16 BYTES BELOW OLDSTACK

 LDX OLDSTACK ;STACK POINTER
 LDA #15  ;#-1 BYTES TO RESTORE
 JMP RESTSTK  ;GO RESTORE
SVESCONT   ;COME HERE AFTER RESTSTK

* IF AUX/MAIN STACKS WERE JUST SWITCHED THEN.
* SAVE THE NEW STACK TO EXT RAM. PUT ALT STACK BYTES
* ,THAT WERE SAVED IN TRACEN, FROM STACK POINTER DOWN
* 16 BYTES TO EXT RAM TO CORRECT FOR NMI VECTORS.

 LDA MSTATE  ;NEW MSTATE
 EOR OLDMSTAT ;HAS STK FLAG CHANGED
 BPL :SAMESTK ;IF NO

 JSR SAVESTK  ;SAVE STACK
 JSR TRANSFR0 ;RESTORE 16 BYTES BELOW POINTER
 DFB RESTALTSC ;code

:SAMESTK
 JSR SVESTK16 ;SAVE 16 BYTES ABOVE STACK POINTER

CONTNMI LDA #%10111111
 AND IERBUFF  ;DISABLE VIAT1 INTERRUPT
 STA IERBUFF

* WAS A NON EXT BRK JUST TRACED ?
 BIT TRCBRK
 BPL :NOBRK  ;IF NO
 LDA $FFFE  ;PUT PROPER BRK VECTOR IN PC
 STA PCLO
 LDA $FFFF  ;HI BYTE
 STA PCHI
 LDA #0
 STA TRCBRK  ;CLEAR FLAG

:NOBRK JMP (ENABLTVC) ;GO TO THE TRACE VECTOR LOCATION


***********************************
* SAVE THE BYTES ABOVE THE STACK POINTER IN USER STACK
* TO EXT STACKBUF

SAVESTK

 LDA #$F8  ;SAVE FROM POINTER UP $F8 BYTES
 BNE SVESTK

SVESTK16
 LDA #16  ;SAVE FROM POINTER UP 16 BYTES

SVESTK PHA   ;NUMBER OF BYTES TO SAVE

 LDX STACK  ;STACK POINTER
 LDY SLOTN0
**********************************
* WARNING, SEGMENT DEPENDENT CODE 		
**********************************
 LDA #%01110000 ;RAM 7, ROM 0
 STA SEGMBASE,Y

 STY YREG  ;SAVE IN RAM7
 PLA   ;NUMBER OF BYTES TO SAVE
 TAY
:NEXT INX
 LDA $0100,X  ;GET FROM STACK
 STA STACKBUF,X ;SAVE IN EXT STACK BUFFER
 DEY
 BNE :NEXT

 LDY YREG  ;SLOTN0
***********************************
* WARNING, SEGMENT DEPENDENT CODE
***********************************
 LDA #%00000000 ;RAM 0, ROM 0
 STA SEGMBASE,Y
 RTS

**********************************
** COME HERE FROM CARD SLOT SPACE*
**********************************

SLOT2K
 STA SLOTCN  ;SAVE SLOTCN
 ASL
 ASL
 ASL
 ASL
 STA SLOTN0  ;SAVE SLOT NUMBER N0

****************************************
* HEY! THIS MUST BE DONE BEFORE ANY TRANSFRS.
*
*** PUT LDA & RTS INSTRUCTIONS IN EXTII RAM
*** THAT MAKE UP LDATEMP ROUTINE, TEMPSEG IS MODIFIED
*** BY TRANSFR BEFORE RUNNING, USED TO LOAD CODE BYTE

 LDA #$AD  ;OPCODE FOR LDA ADDRESS
 STA LDATEMP  ;STORE IN EXTII RAM
 LDA #$60  ;CODE FOR RTS
 STA LDATEMP+3 ;STORE IN EXTII RAM

 CLD
* Init RAM & VIA, display windows
 JSR TRANSFR0 ;INITIALIZE RAM VECTORS & VIA
 DFB INITRAMVC ;CODE

* display version number
* also set carry if exiting with an RTS

 JSR TRANSFR0
 DFB DISVERSC ;code

* DO AN RTS BACK TO USER OR CONTINUE INTO EXT II.?
 BCC TOMAIN10 ;ENTER EXT II

********************
* LEAVE DDT
********************

 STA VIAPCR  ;Set return condition
 RTS   ;RETURN BACK TO USER WITH DDT INITIALIZED

* COME HERE FROM WARM ENTRY OR RESET

ENTEREXT
 JSR ENABWRIT ;Disable all interrupts, put /INIT low
 JSR TRANSFR0 ;ZPAGESAVE, SETMSTAT, DISPON
 DFB WARMINITC ;code
 JMP MAIN10 ;get next command

******************************
*  COMDRT - REAL TIME
******************************

* Run the users program in real time to the matching RTS.
* The current instruction is traced first

COMDRT STA COMRTFLG ;INDICATE COMMAND RT
 LDA #NMICOMRT ;LOW BYTE
 STA ENABLTVC ;TO HI BYTE NMI VECT
 LDA #>NMICOMRT ;HI BYTE
 STA ENABLTVC+1 ;TO LOW BYTE NMI VECT
 JMP STEP1  ;TRACE ANY KIND OF INSTRUCTION

NMICOMRT
 JSR TRANSFR0 ;SET UP FOR REALTIME & GOTO EXECUTE
 DFB SETUPRTC ;code

* returns if a BRK could not be placed at the instruction 
* pointed to by the stacked return address.

 LDA #NOWROM  ;ERROR NUMBER
 BNE ERREXIT0 ;<ALWAYS>

********************************
*  COMDEX
********************************

COMDEX STA EFLAG

********************************
*  COMDTR
********************************

COMDTR EQU *
 BEQ TRACE1  ;NO, DO ONE TRACE
ECOMMAND
 JSR TRANSFR0 ;READ NUMBER
 DFB CHKREADC ;code
 BCC LOADT  ;IF VALID
BADPAR0 LDA #BADPAR  ;ERROR NUMBER

ERREXIT0
 STA $CF00  ;ENABLE EXT RAM
 JSR TRANSFR0 ;INVALID COMMAND
 DFB ERRBEEPC ;CODE BYTE
TOMAIN10 JMP MAIN10

LOADT LDA LETTER1  ;GET L.S. BYTE
 STA TCOUNT+1
 LDA LETTER2  ;GET M.S. BYTE
 STA TCOUNT  ;LOAD TCOUNT
 JMP SKPBRK  ;LOOK FOR BREAK

********************************
*  COMDER
********************************

COMDER STA RTSFLAG

TRACE1 LDX #0
 STX TCOUNT
 INX
 STX TCOUNT+1 ;SET TCOUNT FOR ONE TRACE

*---------------------------------------------
* DO 1 INSTRUCTION, EVEN OUR REAL BREAK, DON'T STOP
* EVEN IF BREAK COUNT REACHES ZERO, THEN
* GO TO THE NMITRC VECTOR LOCATION
* THIS ALLOWS CONTINUING THROUGH A BREAK WITH TR, EX & ER

SKPBRK SEC
 BCS LTRACEVC ;<ALWAYS>

*-----------------------------
* DO 1 INSTRUCTION, EVEN OUR REAL BREAK, BUT
* STOP IF THE BREAK COUNT REACHES ZERO, ELSE GOTO
* NMITRC.

LOOKBRK CLC

LTRACEVC
 LDA #>NMITRC ;USED AS FLAG (ALWAYS > $7F) AND ADDRESS
 STA ENABLTVC+1 ;GO TO NMITRC AFTER TRACING
 LDA #NMITRC  ;.. 1 INSTRUCTION
 STA ENABLTVC
 BCC SKIPTRAC ;DON'T SET STOP FLAG (CARRY) IF CLEAR	

*-----------------------------------
* SAME AS SKPBRK BUT DON'T LOAD NMITRC VECTOR INTO
* ENABLTVC. GO TO THE CURRENT ENABLTVC VECTOR LOCATION
* AFTER DOING 1 INSTRUCTION.

STEP1 SEC
SKIPTRAC
 ROR STOPBRK  ;<$80=STOP IF TOGOFLG=0,>$7F=DON'T STOP
 JSR TRANSFR0 ;IF OUR BRK, DEC TOGO 
 DFB DECTGPCC ;code
 BMI TRACEN  ;NOT BREAK OR NOT OURS
 PHP   ;SAVE STATUS

 SEC
 ROR BRKWFLG  ;NEED TO UPDATE THE BRK WINDOW	 

 BIT STOPBRK  ;STOP IF TOGOFLG = 0 ?
 BMI :CONT  ;IF > $7F THEN DON'T STOP

 LDA TOGOFLG  ;TOGO = 0 ?
 BNE :CONT  ;IF NO
 PLA
 JMP TRACEND  ;STOP & DISPLAY REGISTERS
:CONT PLP
 BNE TRACEN  ;IMPLIED BRK

* DISABLE HARD BREAK SO THE SOFT BREAK IS NOT LOST

 LDA IERBUFF
 STA ETIERSAV ;SAVE IERBUFF
 AND #%11101101
 STA IERBUFF  ;TURN OFF HARD BREAK & BUTTON
 JSR TRANSFR0 ;REPLACE THE 00 WITH ORIGINAL INSTRUCTION BYTE
 DFB REPLACEC ;CODE BYTE

 LDA ENABLTVC ;SAVE THE CURRENT ENABLTVC VECTOR
 STA VECTSAVE
 LDA ENABLTVC+1
 STA VECTSAVE+1

 LDA #BRKTRC  ; --- GO TO BRKTRC AFTER EXECUTING
 STA ENABLTVC ; --- ONE INSTRUCTION
 LDA #>BRKTRC ; --- 
 STA ENABLTVC+1 ; --- 

*-------------------------------------------------
* TRACE N INSTRUCTIONS OF THE TARGET PROGRAM

TRACEN

* CHECK REALTIME & PROGRAM ONLY WINDOWS

 BIT REALTIME ;ARE REALTIME RANGES SET ?
 BNE :CHKPWIN ;IF YES CHECK PROT WINDOW
 BIT PROGONLY ;ARE PROGRAM ONLY RANGES SET ?
 BEQ :NOPR  ;IF NO

* IF YES, K/PC MUST BE INSIDE PROGRAM ONLY RANGE TO BE EXECUTED

:CHKPWIN
 LDX #30
:CHECK LDA PROTADR,X ;GET PROT TYPE
 CMP #"T"  ;CODE TRACE RANGE ?
 BNE :CHKP  ;IF NO
 JSR TRANSFR0 ;IN RANGE ?
 DFB CHKRANGC ;code
 BCC :NEXT  ;IF NO
 LSR COMRTFLG ;INDICATE FROM PROTWIND
 JMP NMICOMRT ;IF YES, RUN SUBROUTINE IN REALTIME
:CHKP CMP #"P"  ;PROGRAM ONLY RANGE ?
 BNE :NEXT
 JSR TRANSFR0 ;IN RANGE ?
 DFB CHKRANGC ;code
 BCS :NOPR  ;IF YES, CONTINUE TRACE
:NEXT SEC
 TXA
 SBC #6  ;NEXT TYPE
 TAX
 BPL :CHECK

* OUT OF RANGES. IF PROG ONLY FLAG IS SET AND WE ARE HERE,
* MUST BE OUTSIDE PROG ONLY WINDOW, SO STOP TRACING &
* INDICATE OUTSIDE PROG RANGE.

 BIT PROGONLY ;ARE PROGRAM ONLY RANGES SET ?
 BEQ :NOPR  ;IF NO
 JSR TRANSFR0 ;OUTSIDE PROG RANGE
 DFB OUTPRGRC ;code
 BCC :NOPR  ;OUR SLOT I/O SPACE IS OK
 JMP COMDDR

:NOPR LDA STACK
 STA OLDSTACK ;SAVE STACK POINTER
 LDA MSTATE
 STA OLDMSTAT ;SAVE OLD MSTATE

* SET TXSFLG IF THE NEXT INSTRUCTION IS TXS OR TCS

 JSR LDAPBRIY ;GET BYTE AT PBR/PC
 STY TXSFLG  ;CLEAR FLAG
 BNE :NOTBRK  ;IF NOT BRK

* IS BRK OUR REALTIME BRK ?

 BIT RTBRKFLG
 BPL :NOTRT  ;IF NOT REALTIME
 TSX   ;IS THIS OUR REALTIME BRK
 CPX RTSTK  ;STACK AT PRE REALTIME LOCAL ?
 BNE :NOTRT  ;IF NOT, CONTINUE
 JSR TRANSFR0 ;RESTORE CHANGED STUFF
 DFB RESTRTC  ;code
 BPL :RTWIND  ;IF RESULT OF RT WINDOW
 JMP COMDDR  ;END COMDRT
:RTWIND JMP SVESCONT ;CONTINUE WITH WHATEVER

* IF INSTRUCTION IS A BRK IT CAN'T BE OURS
* SET PC TO BRK VECTOR & CONTINUE

:NOTRT LDA #$80
 STA TRCBRK  ;INDICATE A BRK WAS TRACED

:NOTBRK CMP #$9A  ;IS IT TXS
 BEQ :TXS  ;IF YES
 CMP #$1B  ;IS IT TCS
 BNE :NOTXS  ;IF NO
:TXS INC TXSFLG  ;SET FLAG

* SAVE 16 BYTES FROM ALT STACK AT STACK POINTER DOWN,
* TO EXT STKBUF, INCASE STACK ARE SWITCHED BY USER PROGRAM.

:NOTXS BIT MSTATE  ;WHICH STACK ARE WE USING NOW
 BMI :SAVMNE  ;IF AUX, THEN SAVE MAIN
 STA AUXZP  ;IF MAIN, THEN SAVE AUX
 BPL :SAVE  ;<ALWAYS>
:SAVMNE STA MAINZP
:SAVE LDX STACK  ;USER STACK POINTER
 LDY #15
:CONT LDA $100,X  ;GET FROM USER STACK
 STA STKBUF,Y ;SAVE IN EXT RAM
 DEX
 DEY
 BPL :CONT
 BIT MSTATE  ;RETURN TO CURRENT STACK
 BMI :AUX  ;RETURN TO AUX
 STA MAINZP  ;RETURN TO MAIN
 BPL :REST
:AUX STA AUXZP  ;RETURN TO AUX

* RESTORE 48 BYTES BELOW THE STACK POINTER IN USER STACK

:REST LDX STACK  ;STACK POINTER
 LDA #47  ;#-1 OF BYTES TO RESTORE

***********************************
* RESTORE BYTES BELOW STACK POINTER FROM EXT BUFFER
* X = USER STACK POINTER
* ACC = # OF BYTES TO RESTORE
* IF COME HERE WITH ACC=15 THEN CONTINUE IN SVESTK ROUTINE
* THIS ROUTINE CAN NOT BE A SUBROUTINE BECAUSE RETURN ADDR
* MIGHT BE OVERWRITTEN.

RESTSTK PHA   ;SAVE
 STA TEMP  ;SAVE
 LDY SLOTN0
**********************************
* WARNING, SEGMENT DEPENDENT CODE 		
**********************************
 LDA #%01110000 ;RAM 7, ROM 0
 STA SEGMBASE,Y

 STY YREG  ;SAVE IN RAM7
 PLA   ;GET # BYTES TO RESTORE
 TAY
:NEXT LDA STACKBUF,X ;GET FROM STACK BUFFER
 STA $0100,X  ;PUT IN STACK
 DEX
 DEY
 BPL :NEXT

 LDY YREG  ;SLOTN0
***********************************
* WARNING, SEGMENT DEPENDENT CODE
***********************************
 LDA #%00000000 ;RAM 0, ROM 0
 STA SEGMBASE,Y
 LDA TEMP
 CMP #15  ;DID WE GET HERE FROM SVESTK
 BNE :CONT  ;IF NO
 JMP SVESCONT ;IF YES

:CONT LDA #%11000000
 STA TFLAG  ;SET TFLAG
 ORA IERBUFF  ;ENABLE TRACE
 STA IERBUFF

**********************************
* TWO NUMBERS WILL WORK FOR COUNTER VALUES WHEN IN 8 BIT MODE.
* ONLY THE SMALLER OF THE TWO WILL WORK WHEN IN 16 BIT MODE.
* MAKE SURE TO USE THE SMALLER NUMBER
**********************************

 LDA #$38  ;COUNTER VALUE, NMI OCCURS
    ; COUNTER+1.5 CLOCK CYCLES AFTER STARTED
 STA VIAT1CL  ;LOW ORDER COUNTER LATCH
 JMP EXECUTE  ;RESTORE REGISTERS AND RUN PROGRAM.

* IF TRACE CAUSES AN NMI THE NMI HANDLER ROUTINE SENDS
* THE COMPUTER TO NMITRC.

BRKTRC LDA ETIERSAV ;GET IERBUFF THAT WAS SAVED
 STA IERBUFF  ;RESTORE
 LDA LETTER3  ;ADDRESS WAS PUT IN LETTER 3,2,1
 STA PBRADD  ;BY VALIDPC OR DECTGPC
 LDA LETTER2
 STA HIADD  ;GET ADDRESS OF INSTRUCTION
 LDA LETTER1
 STA LOWADD
 LDY #0
 TYA
 JSR STAINDY  ;PUT BREAK BACK IN
 INC POINT  ;POINT TO OLD BRK INFO
 INC REALBRK  ;REAL BRK COUNT

 LDA VECTSAVE ;RESTORE TRACE VECTOR
 STA ENABLTVC
 LDA VECTSAVE+1
 STA ENABLTVC+1
 JMP (ENABLTVC) ;GO TO TRACE VECTOR LOCATION

NMITRC LDA EFLAG  ;WAS COMMAND EX ?
 BMI EXCONT  ;IF YES

 BIT RTSFLAG  ;ARE WE LOOKING FOR AN RTS
 BPL :CHKPAS  ;IF NO
 JSR LDAPCIY  ;GET INTRUCTION BYTE
 CMP #$60  ;IS IT AN RTS
 BNE CHKCTRLS ;IF NO
 JMP COMDDR  ;IF YES STOP LOOKING AND DISPLAY REGISTERS.

* DID WE GET HERE FROM THE BREAK HANDLER ?

:CHKPAS BIT PASSFLG
 BPL :CHKTS  ;IF NO
 LDA #0
 STA PASSFLG ;RESET
 JMP EXECUTE ;CONTINUE

:CHKTS BIT TSFLAG  ;IS THIS COMDTS ?
 BMI DOSUB  ;IF YES

 JSR TRANSFR0 ;DISPLAY REG'S FROM RAM & DISASSEM INSTRUCTION
 DFB INITDISRC ;CODE BYTE

* DECREMENT TCOUNT

SKIPREG
 SEC
 LDA TCOUNT+1 ;GET LOW BYTE OF TCOUNT
 SBC #1  ;DECREMENT BY 1
 STA TCOUNT+1 ;STORE
 LDA TCOUNT
 SBC #0  ;SUBTRACT CARRY BIT
 STA TCOUNT
 BNE MORETR  ;MORE TRACING
 LDA TCOUNT+1
 BNE MORETR  ;MORE TRACING
TRACEND BIT PASSFLG  ;DID WE GET HERE FROM A BRK?
 BMI COMDDR  ;IF YES
 BIT EFLAG  ;ARE WE DOING EXECUTE N INSTRUCTIONS?
 BPL LEAVTRC  ;IF NO

**********************************
*  COMDDR
**********************************

COMDDR JSR TRANSFR0 ;IF YES DISPLAY REGISTERS
 DFB INITDISRC ;CODE BYTE
LEAVTRC LDA #0
 STA EFLAG
 STA RTSFLAG
 STA PASSFLG
 JMP MAIN10 ;TRACE FINISHED

EXCONT CMP #"0"  ; EXECUTE PROGRAM UNTIL CTRL-X
 BNE SKIPREG  ; EX COMMAND SO DON'T DISPLAY REGISTERS
MORETR

*CHECK FOR CTRL-S & esc

CHKCTRLS
 BIT IOMODE ;I/O TO SERIAL?
 BMI :SERUSED ;IF YES
 LDA KBD ;READ KEYBOARD
 BPL TOTRACEN ;NO KEYPRESSED SO CONTINUE
 CMP KEY ;IS IT STOP COMMAND
 BNE TOTRACEN ;NO, CONTINUE
 BIT KBDSTRB ;YES, CLEAR KBD
:WAITKEY LDA KBD ;READ KEYBOARD
 BPL :WAITKEY ;WAIT FOR KEYPRESS
 BMI CHKESC ;KEY PRESSED

* USE serial I/O
:SERUSED LDA #$1 ;request code, 'is input ready?'
 JSR TRANSFR0 ;get serial I/O status
 DFB STATPASCC ;code
 BCC TOTRACEN ;no keypress
 JSR TRANSFR0 ;get serial data
 DFB INPASCALC ;code
 CMP KEY ;IS IT stop command?
 BNE CHKESC ;IF NO
WAITSSC JSR TRANSFR0 ;WAIT FOR KEYPRESS
 DFB RECEIVEC ;code

*WAS IT ESC

CHKESC
 CMP #ESC ;IS IT ESC
 BEQ COMDDR ;YES, STOP TRACE
TOTRACEN
 JMP LOOKBRK ;NO, CONTINUE

**** DO THE USERS SUBROUTINE AND STOP IF CARRY IS SET

DOSUB LDX XREG  ;RESTORE REGISTERS
 LDY YREG
 LDA STATUS
 PHA
 LDA ACC
 PLP   ;RESTORE STATUS
 JSR USERSUB  ;DO USER SUB

* COME HERE AFTER USERS RTS

USERRTS CLD   ;IN CASE SET BY USER
 BCC CHKCTRLS ;CONTINUE
 LSR TSFLAG  ;CLEAR TSFLAG
 BPL COMDDR  ;<ALWAYS> STOP

USERSUB JMP (SUBTRACE)

*-------------------------------------------------
* COME HERE WHEN THE HARD BREAK IS REACHED
ETVECTOR
 JSR TRANSFR0 ;CONTINUE IN SEG 2
 DFB ETVCONTC ;code
 JMP MAIN10

********************************
*  COMDTS
********************************

COMDTS EQU *
 JSR TRANSFR0 ;CONTINUE COMMAND IN SEG 4
 DFB TSCONTC  ;code
 BCC :NOERR
 JMP BADPAR0  ;IF ERROR
:NOERR JMP LTRACEVC ;EXECUTE ONE INSTRUCTION IN PROGRAM

*********************************
*  LOCAL SUBROUTINES
*********************************


***** STAINDY AND LDAINDY MAY NOT BE USED TO CHANGE
***** DISPLAY OR OTHER SOFT SWITCHES.

LDAPBRIY   ;LOAD BYTE AT PBR/PC
 LDA PBR
 STA PBRADD
LDAPCIY LDA PCLO  ;LOAD BYTE AT PC
 STA LOWADD
 LDA PCHI
 STA HIADD
 LDY #0

* LDA LOWADD,Y FROM CARD I/O SPACE

LDAINDY LDA #$B9  ;LDA OP,Y OPCODE
 BNE CARDSLT1 ;<ALWAYS>

* STA LOWADD,Y FROM CARD I/O SPACE

STAINDY STA ZBYTE1  ;SAVE
 LDA #$99  ;STA OP,Y OPCODE
CARDSLT1
 STX ZBYTE2  ;SAVE X
 STY ZBYTE3  ;SAVE Y
 STA CXOKLOAD+3+$800 ;PUT IN I/O SPACE ROUTINE

* EXCHANGE ZERO PAGE LOCATIONS IF ACCESS WAS TO ZERO PAGE
 LDA HIADD
 BNE :NOTZPAG ;IF NOT ZERO PAGE
 JSR EXCHZPAG
:NOTZPAG

 LDA STORE80  ;READ CURRENT 80S STATUS
 STA INDY80S  ;SAVE IN BUFFER
 STA STR80OFF ;80 STORE OFF
 LDA ALTZP
 STA INDYBUF  ;SAVE ALTZP FLAG

 LDX PBRADD  ;WHICH BANK
 BEQ :BANK0  ;IF BANK0

* SET BANK OTHER THAN 0
 STX READAUX
 STX WRITAUX
 STX AUXZP
 DEX   ;EXT DISPLAYS RAMWORKS BANK 0 AS BANK 1 etc.
 STX $C073  ;SELECT RAMWORKS BANK
 JMP :TOIO

* SET BANK0
:BANK0 STA READMAIN
 STA WRITMAIN
* comes here on bad bank to force main stack
:BADBANK STA MAINZP

* SAVE 6 BYTES OF THE NEW STACKS RAM
:TOIO TSX
 LDY #5
:SAVE LDA $100,X
 STA STKBUF,Y
 DEX
 DEY
 BPL :SAVE
 LDX ZBYTE2  ;RESTORE
 LDY ZBYTE3

******************************
* ALERT! No stack exists if illegal Ramworks bank is used.
* If stack RAM is bad then force command to LDAPBRIY.
******************************

* check for good stack RAM

 LDA #0
 PHA   ;PUT A ZERO ON THE STACK
 PLA   ;READ IT BACK?
 BNE :BADBANK  ;IF IT DIDN'T READ BACK
 LDA #$55  ;PUT A $55 ON THE STACK
 PHA   ;
 PLA   ;READ IT BACK?
 CMP #$55
 BNE :BADBANK  ;if it didn't read back

* RETURN TO SLOTRTS

 LDA SLOTCN
 PHA
 LDA #SLOTRTS
 PHA

 LDA #SLOTIO  ;LOW ADD BYTE OF SLOT ROUTINE

CARDSLOT
 STA ZBYTE2  ;SAVE ACC
 LDA SLOTCN
 PHA
 LDA ZBYTE2  ;LOW ADDRESS BYTE OF ROUTINE IN SLOT SPACE.
 PHA   ;SET UP STACK
 RTS   ;GO TO ROUTINE IN CARD SLOT SPACE.


****************************************
** EXECUTE THE USERS PROGRAM FROM THE CARD SLOT SPACE

EXECMOVE
 DFB #TOEXECUT
 PLP   ;THESE THREE BYTES ARE MOVED 
 PHP   ;TO THE I/O SPACE ROUTINE
 RTI   ;

***********************************
*  EXECUTE

EXECUTE

* RESTORE THE TEXT PAGE

 JSR TRANSFR0
 DFB RESTTEXTC ;code

* SETUP FOR EXECUTE

 LDX #3
 LDA ACC
 STA ZBYTE1  ;EXPECTED BY SLOTIO
EXSETUP LDA EXECMOVE,X ;SETUP I/O SPACE ROUTINE
 DEX
 BMI CARDSLOT
 STA CXOKLOAD+3+$800,X ;PUT IN I/O SPACE ROUTINE
 BPL EXSETUP  ;<ALWAYS>

***********************************
* SAVE REGISTERS

SAVEREG STA ACC  ;SAVE ACC TO ONBOARD RAM
 PHP
 PLA   ;GET STATUS
SAVXYSP STA STATUS
 STX XREG
 STY YREG
 TSX
 INX
 INX   ;MAKE UP FOR JSR
 STX STACK

**** SAVE RAMRD AND RAMWRT SWITCHES ****

 LDA RAMRD  ;AUX OR MAIN READ
 STA RAMRDBF
 LDA RAMWRT  ;AUX OR MAIN WRITE
 STA RAMWRTBF
 RTS

*** CONTINUATION OF SLOTRTS ONLY!  ***
*** SAVES ZERO PAGE LOCATIONS TO DDT RAM *** 
* RESTORE MEMORY STATE SWITCHES

RTSCONT STA WRITMAIN ;DEFAULT TO MAIN
 BIT RAMWRTBF ;USERS STATE, NOT EXT II STATE
 BPL :CKREAD  ;IF MAIN
 STA WRITAUX  ;NO, WRITE TO AUX
:CKREAD STA READMAIN
 BIT RAMRDBF  ;USERS STATE
 BPL :STR80  ;IF MAIN
 STA READAUX  ;NO, READ FROM AUX
:STR80 LDA INDY80S  ;GET SAVED 80S STATUS
 BPL :OFF  ;KEEP 80 STORE OFF
 STA STR80ON  ;TURN BACK ON
:OFF LDA #0
 STA $C073  ;SELECT RAMWORKS BANK 0

* EXCHANGE ZERO PAGE LOCATIONS IF ACCESS WAS TO ZERO PAGE
 LDA HIADD
 BNE :NOTZPAG ;IF NOT ZERO PAGE
 JSR EXCHZPAG
:NOTZPAG

 LDX ZBYTE2
 LDY ZBYTE3
 LDA ZBYTE1  ;RESTORE
 RTS

*EXCHANGE ZERO PAGE IF ACCESS IS TO ZERO PAGE

EXCHZPAG
 LDX #3  ;4 BYTES
:NEXT LDA BASBUF,X ;GET FROM DDT BUFFER
 LDY BASL,X  ;GET FROM APPLE'S RAM
 STA BASL,X  ;PUT IN APPLE'S RAM
 TYA
 STA BASBUF,X ;PUT IN DDT BUFFER
 DEX
 BPL :NEXT 
 RTS

* ENABWRIT.

ENABWRIT
 LDA #%01111111 ;DISABLE ALL INTERRUPTS
 STA VIAIER  ;ALSO CLEARS BIT 7 OF VIAIFR
ENABINIT
 LDA VIAPCR  ;ENTER HERE TO PUT /INIT LOW
 ORA #%11101110 ;REMOVE INVISIBILITY (CA2 HI) &
; DON'T REPLACE APPLE'S VECTORS (CB2 HI)
 STA VIAPCR
 RTS

* INDEXTO8 SAVE 16 BIT INDEXES AND SET TO 8 BIT.

INDEXTO8
 PHA   ;SAVE ACC 1 BYTE
 JSR ENABINIT ;ALOW WRITING TO EXTRAM
 STX XREG  ;SAVE 1 OR 2 BYTES
 STY YREG  ; " " "
 LDA #$34
 PHA
 PLP   ;KEEP 8 BIT DATA, SET 8 BIT INDEXES

* STZ EMULATE
 STZ EMULATE  ;0 = 65816 MODE
 PLA   ;GET ACC
 STA ACC
 RTS

******** SAVE THE ACC,X AND P REGISTERS *******

SAVEAXP0
 PHP   ;SAVE STATUS
 STX XSAVESEG
 STA ASAVESEG
 PLA   ;GET STATUS
 STA PSAVESEG ;SAVE
 RTS

****** RESTORE THE ACC, X AND P REGISTERS ******

RESTAXP0
 LDX XSAVESEG
 LDA PSAVESEG
 PHA
 LDA ASAVESEG
 PLP
 RTS

***** GLOBAL SUBROUTINES IN THIS SEGMENT *****
***** MAXIMUM OF 32 *****
***** CODE BYTES ARE EQUATED AS FOLLOWS
*
* BITS 0-2 = SEGMENT NUMBER $0 THRU $7 OF SUBROUTINE
* BITS 3-7 = NUMBER OF SUBROUTINE IN SUBTABL

SUBTABL0

LDAINDYC EQU *-SUBTABL0*4+0+$100
 DA LDAINDY-1

STAINDYC EQU *-SUBTABL0*4+0+$100
 DA STAINDY-1

TRACE1C EQU *-SUBTABL0*4+0+$100
 DA TRACE1-1

STEP1C EQU *-SUBTABL0*4+0+$100
 DA STEP1-1

EXECUTEC EQU *-SUBTABL0*4+0+$100
 DA EXECUTE-1

************* SEGMENT CROSSOVER AREA *************

 LST ON
S0END = $CF9D-*
 do nolist
 LST OFF
 fin
 ERR *-1/$CF9D
 DS $CF9D-*,$FF

*** GOTO GETCOMD in segment 5 ***

MAIN10 JSR SAVEAXP0 ;COME HERE TO TRANSFER TO SEGMENT5 DIRECTLY
 LDX SLOTN0
 LDA #%00000101 ;RAM0,ROM5
 STA SEGMBASE,X ;NEXT INSTRUCTION EXECUTED FROM SEGMENT 5
 JSR RESTAXP0 ;RESTORE AFTER TRANSFER FROM SEGMENT 5
 RTS   ;GOTO TO COMMAND IN THIS SEGMENT
 NOP
 NOP   ;MATCH LENGTH WITH SEGMENT 5

* TRANSFER TO OTHER SEGMENTS

TRANSFR0

 JSR SAVEAXP0
 PLA   ;GET RETRUN ADDRESS FROM STACK
 CLC
 ADC #1  ;INC TO POINT AT CODE BYTE
 STA TEMPSEG  ;SETUP LDA TEMPSEG ROUTINE
 PLA
 ADC #0  ;ADD CARRY, IF ANY
 STA TEMPSEG+1 ;SETUP LDA TEMPSEG ROUTINE
 PHA
 LDA TEMPSEG
 PHA   ;BUMP RETURN ADDRESS PAST CODE BYTE
 LDA #0  ;CURRENT SEG #
 PHA
 JSR LDATEMP  ;LOAD CODE BYTE
 STA SEGMCODE ;SAVE CODE
 AND #$07  ;STRIP ALL BUT SEG #
 LDX SLOTN0
 STA SEGMBASE,X ;NEXT INSTR. RUN FROM NEW SEGMENT
* NEW SEGMENT
 LDA #>RETURN0 ;WHERE TO RETURN TO
 PHA
 LDA #RETURN0
 PHA
 LDA SEGMCODE ;CODE BYTE
 AND #$F8  ;STIP OFF SEG# LEAVING SUB #
 LSR
 LSR   ;LEAVE SUB# MULTIPLIED BY 2
* GET ADDRESS OF SUB FROM SUBTABL & PUSH ON STACK
 TAX
 LDA SUBTABL0+1,X ;HI BYTE FIRST
 PHA
 LDA SUBTABL0,X
 PHA

 JSR RESTAXP0 ;RESTORE REGISTERS
 RTS   ;USE RTS TO GOTO SUB

* RETURN HERE FROM SUBROUTINE

RETURN0 EQU *-1
 JSR SAVEAXP0
 PLA   ;SEG # TO RETURN TO
 LDX SLOTN0
 STA SEGMBASE,X ;RETURN TO SEGMENT
 JSR RESTAXP0

*** THIS RTS IS USED BY THE FINDSLOT ROUTINE ***
PUTSLOT RTS   ;RETURN TO CALLING PROGRAM

 DS \,$FF ;PUT OBJECT AT NEXT PAGE
